/**
 * Created by ${PRODUCT_NAME}.
 * User: skylerparr
 * Date: 12/29/10
 * Time: 10:26 PM
 * To change this template use File | Settings | File Templates.
 */
package com.thoughtorigin.module {
import com.thoughtorigin.service.Service;
import com.thoughtorigin.service.ServiceLocator;

import flash.system.ApplicationDomain;
import flash.utils.Dictionary;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;

public class DefaultModuleLoader implements ModuleLoader {

    private var _applicationDomains: Dictionary;
    private var _registeredModules: Dictionary;
    private var _serviceLocator: ServiceLocator;

    public function DefaultModuleLoader() {
        init();
    }

    protected function init(): void {
        _applicationDomains = new Dictionary(true);
        _applicationDomains[Math.random() + ""] = ApplicationDomain.currentDomain;
        _registeredModules = new Dictionary(true);
    }

    public function loadModule(module:Module):void {
        if(!module) return;
        if(_registeredModules[key]) return;

        var key : String = getQualifiedClassName(module);
        _registeredModules[key] = module;
        _applicationDomains[key] = module.applicationDomain;
        for(var service: String in module.services) {
            _serviceLocator.addService(module.services[service]);
        }
    }

    public function unloadModule(module:Module):void {
        if(!module) return;
        var key : String = getQualifiedClassName(module);
        for(var service: String in module.services) {
            _serviceLocator.removeService(module.services[service])
        }
        module.unloadModule();
        module.abstractLoaderInfo.loader.unloadAndStop();
        delete _registeredModules[key];
        delete _applicationDomains[key];
    }

    protected function get registeredModules(): Dictionary {
        return _registeredModules;
    }

    public function get registeredApplicationDomains():Dictionary {
        return _applicationDomains;
    }

   //todo: create test for this.  Gonna need to make a wrapper for ApplicationDomain
    public function getClassByName(name:String):Class {
        for(var appString: String in registeredApplicationDomains) {
            var appDomain: ApplicationDomain = registeredApplicationDomains[appString];
            if(appDomain.hasDefinition(name)) {
                return Class(appDomain.getDefinition(name));
            }
        }
        return null;
    }

    [Inject]
    public function set serviceLocator(value: ServiceLocator): void {
        _serviceLocator = value;
    }
}
}
